#include "chatclient.h"

chatClient::chatClient(QObject *parent) : QObject(parent) {
    socket = new QSslSocket(this);
    userName = "x";
    connect(socket, &QSslSocket::readyRead, this, &chatClient::readMessage);
    connect(socket, &QSslSocket::encrypted, this, &chatClient::onEncrypted);
    connect(socket, &QSslSocket::sslErrors, this, &chatClient::onSslErrors);
    connect(socket, &QSslSocket::disconnected, this, &chatClient::onDisconnected);
    connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::errorOccurred), this, &chatClient::onError);
    setConfig();
    // 连接到服务端
    socket->connectToHostEncrypted("114.132.169.5", 1234);

    if(socket->waitForEncrypted(3000)){
        qDebug()<<"ssl加密成功！";
    }
    //sendMessage("command -query");
}

chatClient::chatClient(QString userName,QString caCertificateFilePath,QString clientCertificateFilePath,QString clientKeyPath,QObject *parent): QObject(parent){
    socket = new QSslSocket(this);

    this->userName = userName;
    connect(socket, &QSslSocket::readyRead, this, &chatClient::readMessage);
    connect(socket, &QSslSocket::encrypted, this, &chatClient::onEncrypted);
    connect(socket, &QSslSocket::sslErrors, this, &chatClient::onSslErrors);
    connect(socket, &QSslSocket::disconnected, this, &chatClient::onDisconnected);
    connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::errorOccurred), this, &chatClient::onError);

    setConfig(caCertificateFilePath,clientCertificateFilePath,clientKeyPath);
    // 连接到服务端
    socket->connectToHostEncrypted("114.132.169.5", 1234);

    if(socket->waitForEncrypted(3000)){
        qDebug()<<"ssl加密成功！";
    }
    //sendMessage("command -query");
}

void chatClient::setConfig(QString caCertificateFilePath,QString clientCertificateFilePath,QString clientKeyPath){
    // 配置 SSL 连接
    QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
    sslConfig.setProtocol(QSsl::TlsV1_2OrLater); // 设置协议版本
    sslConfig.setPeerVerifyMode(QSslSocket::VerifyPeer); // 设置验证模式
    QList<QSslCertificate> caCertificates;
    this->caCertificateFilePath = caCertificateFilePath;
    // 读取第一个证书文件
    QFile file1(caCertificateFilePath);
    if (file1.open(QIODevice::ReadOnly)) {
        QByteArray ca1Data = file1.readAll();
        file1.close();
        QSslCertificate ca1(ca1Data);
        if (!ca1.isNull()) {
            caCertificates.append(ca1);
        } else {
            qWarning() << "Failed to load CA1 certificate from path/to/ca1.pem";
        }
    } else {
        qWarning() << "Failed to open CA1 certificate file at path/to/ca1.pem";
    }
    sslConfig.setCaCertificates(caCertificates);
    socket->setSslConfiguration(sslConfig);

    this->clientCertificateFilePath = clientCertificateFilePath;
    this->clientKeyPath = clientKeyPath;

    QFile certificateFile(clientCertificateFilePath);
    QFile keyFile(clientKeyPath);

    if (!certificateFile.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open certificate file:" << certificateFile.errorString();
        return;
    }

    if (!keyFile.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open key file:" << keyFile.errorString();
        return;
    }

    QSslCertificate Certificate(&certificateFile, QSsl::Pem);
    QSslKey Key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);

    if (Certificate.isNull()) {
        qDebug() << "Invalid server certificate";
        return;
    }

    if (Key.isNull()) {
        qDebug() << "Invalid server key";
        return;
    }

    socket->setLocalCertificate(Certificate);
    socket->setPrivateKey(Key);

}

void chatClient::setConfig(){
    // 配置 SSL 连接
    QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration();
    sslConfig.setProtocol(QSsl::TlsV1_2OrLater); // 设置协议版本
    sslConfig.setPeerVerifyMode(QSslSocket::VerifyPeer); // 设置验证模式
    QList<QSslCertificate> caCertificates;
    caCertificateFilePath = "../证书私钥/CA证书相关/ca.crt";
    // 读取第一个证书文件
    QFile file1(caCertificateFilePath);
    if (file1.open(QIODevice::ReadOnly)) {
        QByteArray ca1Data = file1.readAll();
        file1.close();
        QSslCertificate ca1(ca1Data);
        if (!ca1.isNull()) {
            caCertificates.append(ca1);
        } else {
            qWarning() << "Failed to load CA1 certificate from path/to/ca1.pem";
        }
    } else {
        qWarning() << "Failed to open CA1 certificate file at path/to/ca1.pem";
    }
    sslConfig.setCaCertificates(caCertificates);
    socket->setSslConfiguration(sslConfig);

    clientCertificateFilePath = "../证书私钥/CA证书相关/client1.crt";
    clientKeyPath = "../证书私钥/CA证书相关/client1.key";

    QFile certificateFile(clientCertificateFilePath);
    QFile keyFile(clientKeyPath);

    if (!certificateFile.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open certificate file:" << certificateFile.errorString();
        return;
    }

    if (!keyFile.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open key file:" << keyFile.errorString();
        return;
    }

    QSslCertificate Certificate(&certificateFile, QSsl::Pem);
    QSslKey Key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);

    if (Certificate.isNull()) {
        qDebug() << "Invalid server certificate";
        return;
    }

    if (Key.isNull()) {
        qDebug() << "Invalid server key";
        return;
    }

    socket->setLocalCertificate(Certificate);
    socket->setPrivateKey(Key);

}

void chatClient::readMessage(){
    while (socket->canReadLine()) {
        QString message = QString::fromUtf8(socket->readLine()).trimmed();
        emit receiveMessage(message);
    }
}

void chatClient::onEncrypted()
{
    qDebug() << "Connection encrypted with server";
    // 这里可以处理加密后的连接
    //sendMessage("command -query");
}

void chatClient::onSslErrors(const QList<QSslError> &errors)
{
    qDebug() << "SSL errors with server";
    for (const QSslError &error : errors) {
        qDebug() << "Error:" << error.errorString();
    }
    socket->ignoreSslErrors(); // 你可以选择忽略 SSL 错误
}

void chatClient::onDisconnected()
{
    qDebug() << "Disconnected from server";
}

void chatClient::onError(QAbstractSocket::SocketError socketError)
{
    qDebug() << "Socket error:" << socketError << socket->errorString();
}

void chatClient::sendMessage(const QString &message){
    // // 获取当前的本地时间
    // QDateTime currentTime = QDateTime::currentDateTime();
    qDebug()<<message;
    // // 格式化时间，使用 [yyyy-MM-dd-hh-mm-ss] 格式
    // QString formattedTime = "[" + currentTime.toString("yyyy-MM-dd-hh-mm-ss") + "]";
    if (socket->isOpen() && socket->isEncrypted()) {
        QString message_new = message+"\n";
        socket->write(message_new.toUtf8());
        socket->flush();
        return;
    } else {
        qDebug() << "Socket is not open or not encrypted";
    }
}
